package com.fs.web.base.vo;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fs.web.base.utils.DateUtils;
import com.fs.web.base.utils.StringToolUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * @author ACE
 * @desc 自定义查询容器
 * @creationTime 2019-04-08 16:24
 * @projectName gps-x
 * @packageName com.fs.web.base.vo
 */
public class Criteria<T> extends QueryWrapper<T> {
    private final static String QUERY_SPLIT = "___";
    private final static String QUERY_POSTFIX = "_searchType";
    /**
     * 自动选择查询方式
     * @param data
     * @return
     */
    public QueryWrapper<T> addAuto(Map<String, Object> data){
        if(CollectionUtils.isEmpty(data)) { return new QueryWrapper<T>(); }
        QueryWrapper<T> wrapper = new QueryWrapper<>();
        String format = null;
        for(String fieldName :data.keySet()){
            Object value = data.get(fieldName);
            if(fieldName.endsWith("[]")){
                fieldName = fieldName.replace("[]", "");
            }
            format = fieldName.concat("_format");
            if(data.containsKey(format)){
                format = data.get(format).toString();
            }else{
                format = null;
            }
            value = formatValue(value,format);

            Object opt = null;
            //eg: name=张三___eq
            if(value instanceof String && value.toString().indexOf(QUERY_SPLIT)>-1){
                String[] valueOpt = value.toString().split(QUERY_SPLIT);
                value = valueOpt[0];
                opt = valueOpt[1];
                addAuto(wrapper,fieldName,value,String.valueOf(opt));
            }else{
                if(fieldName.indexOf(QUERY_POSTFIX)>-1) { continue; }
                opt = data.get(fieldName + QUERY_POSTFIX);

                if(opt!=null) {
                    addAuto(wrapper,fieldName,value,String.valueOf(opt));
                }
            }
        }
        return wrapper;
    }

    @SuppressWarnings("unchecked")
    public void addAuto(QueryWrapper<T> wrapper,String fieldName,Object value,String opt){
        if(StringUtils.isBlank(opt)) { opt = "like"; }
        if(value==null || StringUtils.isBlank(fieldName) || StringUtils.isBlank(value.toString())) { return; }
        fieldName = StringToolUtils.HumpToUnderline(fieldName);
        switch (opt) {
            case "like" :
                addLike(wrapper,fieldName, value);
                break;
            case "eq" :
                addEq(wrapper,fieldName, value);
                break;
            case "neq" :
                addNeq(wrapper,fieldName, value);
                break;
            case "gt" :
                addGt(wrapper,fieldName, value);
                break;
            case "gte" :
                addGte(wrapper,fieldName, value);
                break;
            case "lt" :
                addlt(wrapper,fieldName, value);
                break;
            case "lte" :
                addlte(wrapper,fieldName, value);
                break;
            case "in" :
                List<Object> list = new ArrayList<Object>();
                if(value instanceof String[]){
                    list = Arrays.asList((Object[])value);
                }else if(value instanceof Collection<?>){
                    list = (List<Object>) value ;
                }else if(value instanceof String){
                    Object [] v = String.valueOf(value).split(",");
                    list = Arrays.asList(v);
                }
                if(!CollectionUtils.isEmpty(list)) { addIn(wrapper,fieldName, list); }
                break;
            case "between" :
                //在两个数之间
                Object[] values = (Object[]) value;
                int len = values.length;
                if(len >= 1) {
                    addGte(wrapper,fieldName, values[0]);
                }
                if(len >= 2) {
                    addlte(wrapper,fieldName, values[1]);
                }
                break;
            default :
                break;
        }
    }

    private Object formatValue(Object value,String format){
        Object result = null;
        if(StringUtils.isNotBlank(format)){
            if(value instanceof String[]){
                String[] arrays = (String[]) value;
                Object [] objs = new Object[arrays.length];
                for(int i = 0; i < objs.length; i++){
                    objs[i] = format(arrays[i], format);
                }
                result = objs;
            }else{
                result = format(value.toString(), format);
            }
        }else{
            result = value;
        }
        return result;
    }

    private Object format(String v,String format){
        Object value = null;
        if(StringUtils.isNotBlank(v) && StringUtils.isNotBlank(format)){
            try {
                if("dateTime".equals(format)){
                    value = DateUtils.parseDate(v, "yyyy-MM-dd HH:mm:ss");
                }
                if("date".equals(format)){
                    value = DateUtils.parseDate(v, "yyyy-MM-dd");
                }
            } catch (Exception e) {
                System.err.println(v + "转换成"+ format +"格式出现异常！");
            }
        }else{
            value = v;
        }
        return value;
    }

    /**
     * like查询
     * @param value
     * @return
     */
    private void addLike(QueryWrapper<T> wrapper,String fieldName,Object value){
        String v = String.valueOf(value);
        if(StringUtils.isNotBlank(fieldName) && StringUtils.isNotBlank(v)){
            wrapper.like(fieldName,v);
        }
    }
    /**
     * 等于查询
     * @param fieldName
     * @param value
     * @return
     */
    public void addEq(QueryWrapper<T> wrapper,String fieldName,Object value){
        if(StringUtils.isNotBlank(fieldName) && value!=null){
            wrapper.eq(fieldName, value);
        }
    }

    /**
     * 不等于查询
     * @param fieldName
     * @param value
     * @return
     */
    public void addNeq(QueryWrapper<T> wrapper,String fieldName,Object value){
        if(StringUtils.isNotBlank(fieldName) && value!=null){
            wrapper.ne(fieldName, value);
        }
    }

    /**
     * 大于查询
     * @param fieldName
     * @param value
     * @return
     */
    public void addGt(QueryWrapper<T> wrapper,String fieldName,Object value){
        if(StringUtils.isNotBlank(fieldName) && value!=null){
            wrapper.gt(fieldName, value);
        }
    }

    /**
     * 大于等于查询
     * @param fieldName
     * @param value
     * @return
     */
    public void addGte(QueryWrapper<T> wrapper,String fieldName,Object value){
        if(StringUtils.isNotBlank(fieldName) && value!=null){
            wrapper.ge(fieldName, value);
        }
    }

    /**
     * 小于查询
     * @param fieldName
     * @param value
     * @return
     */
    public void addlt(QueryWrapper<T> wrapper,String fieldName,Object value){
        if(StringUtils.isNotBlank(fieldName) && value!=null){
            wrapper.lt(fieldName, value);
        }
    }

    /**
     * 小于等于查询
     * @param fieldName
     * @param value
     * @return
     */
    public void addlte(QueryWrapper<T> wrapper,String fieldName,Object value){
        if(StringUtils.isNotBlank(fieldName) && value!=null){
            wrapper.le(fieldName, value);
        }
    }

    @SuppressWarnings("rawtypes")
    public void addIn(QueryWrapper<T> wrapper,String fieldName,Collection value){
        if(StringUtils.isNotBlank(fieldName) && !CollectionUtils.isEmpty(value)){
            wrapper.in(fieldName, value);
        }
    }
}
